<template>
  <div>
    <el-button @click="requestAll">并发请求</el-button>
    <el-button @click="requestSeriale">串发请求</el-button>
    <el-button @click="testTimeout">延时 console</el-button>
    <el-button @click="loadImg">loadImg</el-button>
    <ul v-loading="isLoading">
      <li v-for="(item,index) in list" :key="index">
        {{ index }} &nbsp;&nbsp;{{ item.test2 }}
      </li>
    </ul>

    <div ref="imgWrap" />
  </div>
</template>

<script>
import { createfactories, timeout, loadimgAsync } from './createPromise'
const api = 'http://rap2.taobao.org:38080/app/mock/data/1167705'
import axios from 'axios'

export default {
  data() {
    return {
      isLoading: false,
      list: []
    }
  },
  created() {
    // this.requestAll()
    // 测试在一个promise的resolve方法中传入另外一个promise
    // this.testPromiseConnect()

    this.testThenChain()
  },
  methods: {
    // 测试在一个promise的resolve方法中传入另外一个promise
    testPromiseConnect() {
      const p1 = new Promise((resolve, reject) => {
        timeout(2000).then(res => {
          // reject(new Error('testPromiseConnect 第一个'));
          resolve('testPromiseConnect 第一个')
        })
      })

      const p2 = new Promise(resolve => {
        timeout(0).then(res => {
          console.log('testPromiseConnect 第二个')
          resolve(p1)
        })
      })

      // 这里2S后才执行，因为 p1 2S后才改变状态，导致当前的promise 也是2s后才改变状态。
      p2.then((res, arg) => {
        console.log(res, arg)
      }, err => {
        console.error(err)
      })
    },
    // 测试在一个then方法中return 一个promise 然后再链式调用then方法
    testThenChain() {
      Promise.resolve(1).then(res => {
        console.log('testThenChain1')
        return timeout(1000)
      }).then(res => {
        console.log('testThenChain2')
        console.log(res) // 这里的res 应该是 Promise.resolve(2)还是2？
        // 结果是2
      })
    },
    testTimeout() {
      const wait = 1000
      /**
       * 问题：一个promise 实例可以调用多次then方法指定多个回调处理吗？
      */
      const resultPromise = timeout(wait, 'a')
      resultPromise.then(res => {
        console.log(res + '1')
      })
      resultPromise.then(res => {
        console.log(res + '2')
      })
    },
    loadImg() {
      loadimgAsync('http://udata.youban.com/webimg/vip/holidays/200319activity/vip_banner05.png?v=1').then(res => {
        this.$refs.imgWrap.appendChild(res)
      })
    },
    async requestAll() {
      this.list = []
      // 创建n个请求对象
      const n = 1000
      const requestArray = []
      for (let i = 0; i < n; i++) {
        requestArray.push(axios.get(api).then(res => res.data))
      }
      // 并发请求
      try {
        const res = await Promise.all(requestArray)
        if (res) {
          this.list = res
        }
      } catch (err) {
        console.error(err)
      }
    },
    // 串发请求
    async requestSeriale() {
      const createPromise = createfactories(1, 200)
      this.list = []
      // 创建n个请求对象
      const n = 100
      const requestArray = []
      for (let i = 0; i <= n; i++) {
        requestArray.push(createPromise)
      }
      // requestArray=[fn,fn,fn,fn,...]

      // 如果想在串行请求执行完之后返回一个大数组（包含所有数据），就不能做到界面上的串行加载效果。
      // 但在实际开发中会有这样的需求，(后一个接口需要前一个接口返回的数据作为参数);
      // 比如异步求和，每个接口返回一个数字，计算前n个数字相加的和。 n为0~n;

      /**
       * 串行接口最后一次请求也仅返回自己的数据。
       * 要处理所有请求的数据，需要额外做处理。
      */
      const serialPromises = (requestArray) => {
        // const arr = []
        return requestArray.reduce((prev, next) => {
          return prev.then((preVal) => {
            if (preVal) {
              this.list.push(preVal)
            }
            return next()
          })
        }, Promise.resolve())
      }

      serialPromises(requestArray)
    }
  }
}
</script>
<style>

</style>
